#pragma once
#include "quaternion.h"

#define TEMPLATE template<typename T>
#define QUATERNION QuaternionT<T>

BEGIN_NAMESPACE_OXGE

//
TEMPLATE
const QUATERNION QUATERNION::ZERO(0,0,0,0);

TEMPLATE
const QUATERNION QUATERNION::UNIT_W(1,0,0,0);

TEMPLATE
const QUATERNION QUATERNION::UNIT_X(0,1,0,0);

TEMPLATE
const QUATERNION QUATERNION::UNIT_Y(0,0,1,0);

TEMPLATE 
const QUATERNION QUATERNION::UNIT_Z(0,0,0,1);

TEMPLATE
const QUATERNION QUATERNION::UNIT_SCALE(1,1,1,1);

//
TEMPLATE 
const typename QUATERNION::MatrixType QUATERNION::UNIT_X_MAT( 0,1, 0,0,
											 -1,0, 0,0,
											 0,0, 0,1,
											 0,0,-1,0);

TEMPLATE 
const typename QUATERNION::MatrixType QUATERNION::UNIT_Y_MAT(0,0, 0,-1,
											 0,0,-1, 0,
											 0,1, 0, 0,
											 1,0, 0, 0);

TEMPLATE 
const typename QUATERNION::MatrixType QUATERNION::UNIT_Z_MAT(0, 0,-1,0,
											 0, 0, 0,1,
											 1, 0, 0,0,
											 0,-1, 0,0);


TEMPLATE 
const typename QUATERNION::MatrixType QUATERNION::UNIT_W_MAT(1,0,0,0,
											 0,1,0,0,
											 0,0,1,0,
											 0,0,0,1);



TEMPLATE
QUATERNION QUATERNION::operator*(const QUATERNION& quatR)const
{
	return QuatType( a1 * quatR.a1 - a2*quatR.a2 - a3*quatR.a3 - a4*quatR.a4, 
		a1 * quatR.a2 + a2*quatR.a1 + a3*quatR.a4 - a4*quatR.a3,
		a1 * quatR.a3 - a2*quatR.a4 + a3*quatR.a1 + a4*quatR.a2,
		a1 * quatR.a4 + a2*quatR.a3 - a3*quatR.a2 + a4*quatR.a1 );
}


TEMPLATE
void QUATERNION::UnitTest()
{
	QuatType quat;
	quat.GetMatrix();
	QuatType quat2;
	quat * quat2;
}


END_NAMESPACE_OXGE



#undef TEMPLATE
#undef QUATERNION